#include "hall_sensor.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

/**
 * @brief 初始化霍尔传感器的 GPIO 引脚
 */
void Hall_Sensor_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* 启用 GPIOB 和 GPIOC 时钟 */
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    /* 配置霍尔传感器引脚：PB10, PB0, PC5 */
    GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_5;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

/**
 * @brief 
 * 
 * @retval uint8_t 返回霍尔传感器的状态，按位表示三个传感器的状态
 */
uint8_t Read_Hall_Sensor(void)
{
  uint8_t hall_state = 0;
  if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10) == GPIO_PIN_SET)
  {
    hall_state |= (1 << 0);
  }

  /* 读取 PB0 状态 */
  if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_SET)
  {
    hall_state |= (1 << 1);
  }

  /* 读取 PC5 状态 */
  if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == GPIO_PIN_SET)
  {
    hall_state |= (1 << 2);
  }

  return hall_state;
}

/**
 * @brief 将霍尔传感器的状态映射到 0 ~ 2PI 的角度
 * 
 * @param hall_state 霍尔传感器的状态
 * @retval float 返回映射到 0 ~ 2PI 的角度
 */
float Hall_Angle(void)
{
  uint8_t hall_state = Read_Hall_Sensor();
  switch (hall_state)
  {
  case 1: return (float)M_PI / 3.0f;              // 0 radians
  case 3: return 2.0f * (float)M_PI / 3.0f;       // π/3 radians
  case 2: return (float)M_PI;                    // 2π/3 radians
  case 6: return 4.0f * (float)M_PI / 3.0f;      // π radians
  case 4: return 5.0f * (float)M_PI / 3.0f;      // 4π/3 radians
  case 5: return 0.0f;                           // 5π/3 radians
  default: return -1.0f;                         // Invalid state
  }
}
